#include "mysqlapi.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdio.h>

// 插入的数据个数
#define DATA_NUM 10

char gVecAddress[][15] = {"BenJing", "ShangHai", "GuangZhou", "ShenZhen", "HangZhou", "WuHan", "ChengDu", "NanJing",
					"TianJin", "XiAn", "ChangSha", "ZhengZhou", "ShenYang", "ChongQing", "QingDao"};


MySqlApi::MySqlApi(){
    mysql_init(&mysql);  
}

MySqlApi::~MySqlApi(){
    mysql_close(&mysql);
}

bool MySqlApi::connToDb(std::string host, std::string userName, std::string pwd, std::string dbName){
    MYSQL *msl = mysql_real_connect(&mysql, host.c_str(), userName.c_str(), pwd.c_str(), dbName.c_str(), 0, NULL, 0);
	if(msl == NULL){
        printf("connect failed, %s\n",mysql_error(&mysql));
		return false;
	}

    printf("connect success.\n");
    return true;
}

bool MySqlApi::createTable(std::string tbName){
    int bRet = mysql_query(&mysql, "create table person(id INT PRIMARY KEY, name VARCHAR(30), age INT, phone VARCHAR(12)," 
                "email VARCHAR(30), city VARCHAR(20));");
    if(bRet != 0){
        printf("create table failed, %s\n",mysql_error(&mysql));
        return false;
    }
    return true;
}

bool MySqlApi::selectData(std::string tbName){
    char cSql[1024] = { 0 };
    sprintf(cSql, "select * from %s;", tbName.c_str());
    
    if(mysql_real_query(&mysql, cSql, strlen(cSql)) != 0){
    	printf("select failed, %s\n", mysql_error(&mysql));
        return false;
   	}

   	MYSQL_RES* res = mysql_store_result(&mysql);
    if(NULL == res){
        printf("res is null, %s\n", mysql_error(&mysql));
        return false;
   	}

    int fNum = mysql_num_fields(res);     //返回值为结果集中记录的数量
    MYSQL_FIELD *fields = mysql_fetch_fields(res); 

	//获取字段名
    for(int i = 0; i < fNum; i++){
    	printf("%s\t", fields[i].name);
	}
    printf("\n");
		
    // 获取结果集    
    MYSQL_ROW row;
   	while(row = mysql_fetch_row(res)){   //检索结果集的一条记录，返回值为下一行的结构
    	for(int i = 0; i < fNum; i++){
            printf("%s\t", row[i]);
        }
    	printf("\n");
  	}


    mysql_free_result(res);   //释放结果集

    return true;
}

bool MySqlApi::insertData(std::string tbName){
    // 初始化随机数种子
    srand(time(NULL));
	
	char csql[1024] = { 0 };
	for(int i = 1; i < DATA_NUM + 1; i++){
		memset(csql, 0, 1024);
		sprintf(csql, "insert into %s(id,name,age,phone,email,city) values(%d,'%s',%d,'%s','%s','%s');",
				tbName.c_str(),
                i,
				generate_random_name().c_str(),
				generate_random_int(18, 60),
				generate_random_phone().c_str(),
				generate_random_email().c_str(),
				generate_random_city().c_str()
				);	
		printf("csql: %s\n", csql);
		if(mysql_query(&mysql, csql) != 0){	
			printf("insert failed, %s\n",mysql_error(&mysql));
			return false;	
		}
	}
    return true;
}

bool MySqlApi::delData(std::string tbName){
    char cSql[1024] = { 0 };
    sprintf(cSql, "delete from %s;", tbName.c_str());

    int bRet = mysql_query(&mysql, cSql);
	if(bRet != 0){
		printf("delete failed.  %s\n",mysql_error(&mysql));
		return false;
	}
	return true;
}

int MySqlApi::generate_random_int(int min, int max){
    if (min > max) {
        printf("min > max, failed.\n");
        return -1;
    }

    // 计算范围
    int range = max - min + 1;

    // 生成随机数并调整到指定范围
    return rand() % range + min;
}

std::string MySqlApi::generate_random_phone(){
	std::string phone_num = "1";
	for(int i =0; i < 10; i++){
        char cbuf[12] = { 0 };
        my_itoa(rand() % 10, cbuf);
		phone_num += cbuf;
	}
	return phone_num;
}

std::string MySqlApi::generate_random_email(){
	std::string email_num;
	for(int i = 0; i < 9; i++){
        char cbuf[12] = { 0 };
        my_itoa(rand() % 10, cbuf);
        email_num += cbuf;
	}
	email_num += "@qq.com";
	return email_num;
}

std::string MySqlApi::generate_random_name(){
	std::string name_str;
	name_str = 'A' + rand() % 26;
	for(int i = 0; i < 3; i++){
		name_str += 'a' + rand() % 26;
	}
	return name_str;
}

std::string MySqlApi::generate_random_city(){
	std::string city_str;
	city_str = gVecAddress[rand() % 15];
	return city_str;
}

void MySqlApi::my_itoa(int num, char *str) { 
    int i = 0;
    int isNegative = 0;

    // 处理0的特殊情况
    if (num == 0) {
        str[i++] = '0';
        str[i] = '\0';
        return;
    }

    // 判断是否是负数
    if (num < 0) {
        isNegative = 1;
        num = -num;
    }

    // 转换数字到字符
    while (num != 0) {
        int rem = num % 10;
        str[i++] = (rem < 10) ? rem + '0' : rem + 'A' - 10;
        num /= 10;
    }

    // 如果是负数，添加负号
    if (isNegative) {
        str[i++] = '-';
    }

    str[i] = '\0';

    // 因为上面的操作会使得数字倒序存放，所以需要反转字符串
    for (int start = 0, end = i - 1; start < end; start++, end--) {
        char temp = str[start];
        str[start] = str[end];
        str[end] = temp;
    }
}
